-
Notifications
You must be signed in to change notification settings - Fork 1.4k
Introducing AVA snapshots v3 #2685
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
This index was used to establish declaration order of beforeEach and afterEach hooks. Since these hooks no longer support snapshots, associatedTaskIndex is unnecessary.
This index was used to establish declaration order of snapshots with ids. Since snapshots with ids are no longer supported, this index is unnecessary.
This format contains all the necessary information for regenerating snapshot reports (test titles, snapshot labels, snapshot ordering) but isn't designed for robustness of any sort, only ease of implementation. Once a proof of concept is ready, the format should be revisited.
This requires deleting all the .snap files, as well as modifying contains-only.js and then putting it back after.
Still prohibit removing snapshots when any block was skipped.
This enables unit tests to continue using Runners without snapshot support, while allowing Runner to use the snapshot manager interface as though it was pre-loaded.
Including test.only(), --match, and line number selection.
Better conveys the purpose of the test suite. Clarifies the PR diff, since the old snapshot-updates is being entirely removed and replaced.
Looks like the testing approach I've been using here and in Most of these tests are creating a temporary directory, copying a fixture, running AVA once to set up some initial state, running AVA again to modify that state, checking that the change matches the expectation, and then cleaning up the temporary directory. (The windows runs are somehow timing out within the first fixture execution, which is very strange.) I'll have to rethink this & hopefully eliminate some of those steps and/or reorganize the tests to run in a timeout-friendly pattern. |
Shall we update this to SHA-256? Just to deal with projects that rule out insecure hashes throughout the codebase. |
Our only concern should be being able to read snapshots written by previous minor versions (within the same major release). A test using a new API won't pass when used with an older version either. |
The CBOR spec itself makes a big deal about determinism, so hopefully this will be rare. |
Why does it need to be loaded eagerly? Could we load it synchronously when needed? |
Although, of course, if there is no snapshot file this is a cheap operation, and if there is, it's likely needed. So this is fine, never mind 😄 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- When the snapshot report is changed, tests not touched in that run (e.g. removed tests, tests which no longer use snapshots) are moved to the end of the report, maintaining their previous order among themselves.
What happens when tests are skipped? Are those sections moved to the end as well? We should have access to the declaration order.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm going to need some more time to review this. Impressive work @ninevra.
Tests that are skipped should remain ordered properly. (edit: this is demonstrated by the snapshot for Currently, ordering info is collected for tests that are skipped (or "not selected" by other means) or that use It's possible to collect ordering info for all tests that are declared, whether they use snapshots or not; I'd add a
Plus, in theory eager loading should make the performance characteristics of snapshot-based tests a little more consistent; before, the first
I expect it should be rare, yes. I'm invoking
Sounds good to me. I'll hopefully have time to make changes in a day or two.
Makes sense. Should we consider including a minor and/or patch version in the
A shared worker could only control parallelism across the test files where it was loaded, though, right? That is, if it was loaded in |
Keep docs accurate for AVA 3. Co-authored-by: Mark Wubben <[email protected]>
What scenario would this cover? Adding a new snapshot assertion to an existing test which is run selectively? Though that would still order correctly right?
I don't think the warnings are worthwhile. Either it's a hard error, and then a single major version suffices, or handling in newer versions deals with missing fields. Which is needed anyway to ensure CI passes when a newer (minor / patch) AVA version is installed and snapshots haven't been updated.
You're right, yes. Controlling overall execution could be an interesting concept, but possibly something that AVA should provide a framework for but not provide out of the box. |
The blocksByTitle format is an implementation detail of Manager, whereas the CBOR data structure is a characteristic of the snapshot file protocol. This change reduces codepath duplication between generateReport() and encodeSnapshots(), and avoids passing blockIndices around everywhere. If decodeSnapshots() and encodeSnapshots() are later exposed as a library, this may be closer to the desired interface.
Switched to sha256 hashes and implemented the
It covers some narrow edge cases. For instance, if a test had its snapshot assertions removed, it's snapshot data would be retained but, since it wasn't skipped and no longer used snapshots, so the Collecting ordering info for every test also just seems a little easier to reason about. |
@ninevra I've pushed some small tweaks, let me know what you think. In the snapshot format I renamed Your tests seem very thorough. There's a lot of it though, so it's hard to review! Any tips? Or else let's just ship it 😄 |
Hopefully will make the snapshot-worker snapshots easier to read.
@novemberborn all the tweaks look great to me! Especially the
I mean, I don't think we should ship code you're not confident in, and I certainly don't intend to pressure you to do that. I am sorry that the diff ended up so massive. What can I do to make the code and/or tests easier to review/maintain? Ideas:
|
I have a crude-but-working implementation of the shared worker concurrency limiter we discussed; it's on ninevra/ava/snapshot-regenerate-shared-worker-semaphore. I think landing that here would require updating avajs/test to expose Would you be interested in a PR to add semaphores to |
That'd be perfect for
That'd be fine, except that shared workers are still experimental and subject to breaking changes even in patch releases of AVA. I'm not sure we should be relying on that in our own test suite shipping AVA would break its tests. |
It's very meta, but also very helpful. Thanks! I think I got side tracked by all the fixtures. Once I skipped those it got a lot easier. Great work. |
🎊 |
Implements a new snapshot file format containing all information necessary to generate the snapshot report file.
Allows the use of
test.skip()
,test.only()
,--match
, line number selection, andt.snapshot.skip()
during--update-snapshots
runs.Closes #2634 by removing the "Could not update snapshots" case entirely.
Closes #2635 by allowing existing test & assertion selection mechanisms to be used with
--update-snapshots
.Hopefully will assist with #1768 and #2099.
Current proposed snapshot file format:
AVA Snapshot v3\n
Notes:
label
field is absent unless the user supplied a label. This allows changing the default snapshot label if desired in the future.buffer
field may be absent, if the snapshot has only ever been skipped. Such snapshots are currently rendered as<No Data>
.Pros of the proposed format:
--update-snapshots
Cons of the proposed format:
Other changes:
Frontend:
--update-snaphots
now maintains declaration-order.Edge cases:
--update-snapshots
is passed and the only use of snapshots is in discardedt.try()
attempts, then the snapshot file is removed. There's no snapshot data to record in this case, so I don't see any reason to keep the file.t.snapshot.skip(); t.snapshot();
is added at the end of a test,RangeError
is no longer thrown; instead a "blank space" is recorded for the skipped snapshot. This is currently rendered in the snapshot report as<No Data>
.snapshot-manager
now assumesArray.prototype.sort
is stable. This is the true in all supported Node versions afaik, and is required by the standard as of ecmascript 2019, but notably is false in node v10. IfArray.prototype.sort
is not stable, the snapshot report order may not be deterministic.Backend:
Runner
constructor, rather than lazily loaded.Runner
always emits a dependency on its.snap
file, even in--update-snapshots
mode and even if no snapshot assertions are performed.cbor
.md5-hex
.TODO:
.snap
files--update-snapshots
withtest.skip()
,t.snapshot.skip()
,test.only()
,--match
, line number selectionskipBlock()
andskipSnapshot()
, not once at load timecleanSnapshots()
fits more naturally as part ofManager#save()
. But,Runner
's lazy-loading behavior, which in turn is relied on by existingRunner
unit-test suites.cannotSave
events